@file:Suppress("NAME_SHADOWING")

package cn.mujiankeji.mbrowser.工具.操作


import cn.mujiankeji.mbrowser.app.应用接口
import cn.mujiankeji.mbrowser.工具.网络.网络操作
import cn.mujiankeji.mbrowser.数据.数据库.AppDatabase
import cn.mujiankeji.mbrowser.数据.数据库.DBQzm
import cn.mujiankeji.mbrowser.数据.数据库.DBQzmBag
import cn.mujiankeji.mbrowser.数据.枚举类.快照类型枚举
import kotlinx.serialization.Serializable
import org.json.JSONObject
import org.koin.core.context.GlobalContext

object 快照操作 {


    @Serializable
    private data class ItemJson(
        val name : String,
        val url : String, // 匹配的地址
        val type : String,
        val rule : String,
    )

    @Serializable
    private data class BagJson(
        val name : String,
        val uid : String,
        val version : Int,
        val rules : List<ItemJson>
    )


    suspend fun 添加订阅(url : String,database : AppDatabase = GlobalContext.get().get()) : DBQzmBag?{
        var name = 地址操作.取文件名(url,false)
        if (name.isEmpty()) name = "未命名"

        val bag = DBQzmBag(名称 = name)

        val json = 网络操作.获取文本(url) ?: return null

        var jsonObject : BagJson = try {
            val jsonObj = JSONObject(json)
            BagJson(name = jsonObj.getString("name"),
                uid = jsonObj.getString("uid"),
                version = jsonObj.getInt("version"),
                rules = jsonObj.getJSONArray("rules").let {
                    val ls = ArrayList<ItemJson>()
                    for (i in 0 until it.length()) {
                        val item = it.getJSONObject(i)
                        ls.add(
                            ItemJson(name = item.getString("name"),
                                url = item.getString("url"),
                                type = item.getString("type"),
                                rule = item.getJSONObject("rule").toString())
                        )
                    }
                    ls
                })
        }
        catch (_ : Exception){
            应用接口.输出提示("失败:规则不合规")
            return null
        }

        bag.订阅地址 = url
        bag.更新时间 = System.currentTimeMillis()
        bag.版本 = jsonObject.version
        bag.名称 = jsonObject.name
        bag.uid = jsonObject.uid

        bag.id = database.快照包().插入订阅(bag)
        return bag
    }

    suspend fun 更新快照订阅包(old : DBQzmBag, url : String){
        val database = GlobalContext.get().get<AppDatabase>()
        // ResourceUtils.readAssets2String("qzm/test.json")//
        val json : String = 网络操作.获取文本(url)?:return
        val bag : BagJson = json.let { code->
            if (code.isEmpty()) return
            val json = JSONObject(code)
            BagJson(name = json.getString("name"),
                uid = json.getString("uid"),
                version = json.getInt("version"),
                rules = json.getJSONArray("rules").let {
                    val ls = ArrayList<ItemJson>()
                    for (i in 0 until it.length()) {
                        val item = it.getJSONObject(i)
                        ls.add(
                            ItemJson(name = item.getString("name"),
                            url = item.getString("url"),
                            type = item.getString("type"),
                            rule = item.getJSONObject("rule").toString())
                        )
                    }
                    ls
                })
        }

        old.订阅地址 = url
        old.更新时间 = System.currentTimeMillis()
        old.版本 = bag.version
        old.名称 = bag.name
        old.uid = bag.uid

        // 先清空合集，再独自更新
        database.快照().删除合集(old.uid)

        // 处理合集
        bag.rules.forEach {
            val type = try {
                快照类型枚举.valueOf(it.type)
            }catch (e : Exception){
                // todo 无法识别该类型
                null
            }
            if (type != null){
                DBQzm(bid = old.uid,
                    名称 = it.name,
                    匹配地址 = it.url,
                    类型 = type,
                    规则内容 = it.rule.toString(),
                    启用 = true,
                    更新时间 = System.currentTimeMillis())
                    .let {
                        database.快照().插入规则(it)
                    }
            }

        }
        if (old.id == 0L){
            old.id = database.快照包().插入订阅(old)
        }else{
            database.快照包().更新订阅(old)
        }
    }


}